home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************************
-
- Gnucleus - A node application for the Gnutella network
- Copyright (C) 2000 John Marshall
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
- For support, questions, comments, etc...
- E-Mail:
- swabby@c0re.net
-
- Address:
- 21 Cadogan Way
- Nashua, NH, USA 03062
-
- ********************************************************************************/
-
- // ViewTransfer.cpp : implementation file
- //
-
- #include "stdafx.h"
- #include "Gnucleus.h"
- #include "MainFrm.h"
-
- #include "GnucleusDoc.h"
- #include "ViewSearch.h"
-
- #include "GnuTransfer.h"
- #include "GnuHash.h"
- #include "GnuSock.h"
- #include "GnuControl.h"
-
- #include "ViewTransfer.h"
-
- #include "Base64.h"
-
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // CViewTransfer
-
- IMPLEMENT_DYNCREATE(CViewTransfer, CFormView)
-
- CViewTransfer::CViewTransfer()
- : CFormView(CViewTransfer::IDD)
- {
- //{{AFX_DATA_INIT(CViewTransfer)
- // NOTE: the ClassWizard will add member initialization here
- //}}AFX_DATA_INIT
-
- UpdateRate = 0;
- FiveSecs = 0;
-
- m_bItemsChanged = false;
- }
-
- CViewTransfer::~CViewTransfer()
- {
- }
-
- void CViewTransfer::DoDataExchange(CDataExchange* pDX)
- {
- CFormView::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CViewTransfer)
- DDX_Control(pDX, IDC_BUTTON_CANCEL_DOWN, m_CancelDown);
- DDX_Control(pDX, IDC_BUTTON_CANCEL_UP, m_CancelUp);
- DDX_Control(pDX, IDC_BUTTON_PAUSE, m_btnPause);
- DDX_Control(pDX, IDC_STATIC_UPLOADS, m_stcUploads);
- DDX_Control(pDX, IDC_STATIC_DOWNLOADS, m_stcDownloads);
- DDX_Control(pDX, IDC_LIST_UPLOADS, m_lstUploads);
- DDX_Control(pDX, IDC_LIST_DOWNLOADS, m_lstDownloads);
- //}}AFX_DATA_MAP
- }
-
-
- BEGIN_MESSAGE_MAP(CViewTransfer, CFormView)
- //{{AFX_MSG_MAP(CViewTransfer)
- ON_WM_SIZE()
- ON_WM_TIMER()
- ON_BN_CLICKED(IDC_BUTTON_CANCEL_DOWN, OnButtonCancelDown)
- ON_BN_CLICKED(IDC_BUTTON_CANCEL_UP, OnButtonCancelUp)
- ON_BN_CLICKED(IDC_BUTTON_PAUSE, OnButtonPause)
- ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_DOWNLOADS, OnItemchangedListDownloads)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- /////////////////////////////////////////////////////////////////////////////
- // CViewTransfer diagnostics
-
- #ifdef _DEBUG
- void CViewTransfer::AssertValid() const
- {
- CFormView::AssertValid();
- }
-
- void CViewTransfer::Dump(CDumpContext& dc) const
- {
- CFormView::Dump(dc);
- }
- #endif //_DEBUG
-
- /////////////////////////////////////////////////////////////////////////////
- // CViewTransfer message handlers
-
- void CViewTransfer::OnInitialUpdate()
- {
- CFormView::OnInitialUpdate();
-
- Doc = (CGnucleusDoc *) GetDocument();
-
- // Initialize the list control
- int offSet;
-
- if(m_lstDownloads.GetScrollLimit(SB_VERT))
- offSet = ::GetSystemMetrics(SM_CXVSCROLL) + 3;
- else
- offSet = 4;
-
- CRect rect;
- m_lstDownloads.GetWindowRect(&rect);
-
- m_lstDownloads.InsertColumn(0, "File", LVCFMT_LEFT,
- (rect.Width() - offSet) * 2/6, 0);
- m_lstDownloads.InsertColumn(1, "Bytes", LVCFMT_RIGHT,
- (rect.Width() - offSet) * 1/6, 1);
- m_lstDownloads.InsertColumn( 2, "Status", LVCFMT_LEFT,
- (rect.Width() - offSet) * 1/6, 2);
- m_lstDownloads.InsertColumn( 3, "Completed", LVCFMT_LEFT,
- (rect.Width() - offSet) * 1/6, 3);
- m_lstDownloads.InsertColumn( 4, "Rate", LVCFMT_RIGHT,
- (rect.Width() - offSet) * 1/6, 4);
-
- m_lstDownloads.SetExtendedStyle(LVS_EX_FULLROWSELECT);
-
-
- if(m_lstUploads.GetScrollLimit(SB_VERT))
- offSet = ::GetSystemMetrics(SM_CXVSCROLL) + 3;
- else
- offSet = 4;
-
- m_lstUploads.GetWindowRect(&rect);
-
- m_lstUploads.InsertColumn(0, "File", LVCFMT_LEFT,
- (rect.Width() - offSet) * 2/6, 0);
- m_lstUploads.InsertColumn(1, "Bytes", LVCFMT_RIGHT,
- (rect.Width() - offSet) * 1/6, 1);
- m_lstUploads.InsertColumn( 2, "Status", LVCFMT_LEFT,
- (rect.Width() - offSet) * 1/6, 2);
- m_lstUploads.InsertColumn( 3, "Completed", LVCFMT_LEFT,
- (rect.Width() - offSet) * 1/6, 3);
- m_lstUploads.InsertColumn( 4, "Rate", LVCFMT_RIGHT,
- (rect.Width() - offSet) * 1/6, 4);
-
- m_lstUploads.SetExtendedStyle(LVS_EX_FULLROWSELECT);
-
- // Set image lists
- m_lstDownloads.SetImageList(GetSharedImageList(), LVSIL_SMALL);
- m_lstUploads.SetImageList(GetSharedImageList(), LVSIL_SMALL);
-
- // Disable buttons
- m_btnPause.EnableWindow(FALSE);
- m_CancelDown.EnableWindow(FALSE);
-
- // Set the timer
- DownloadTimer = SetTimer(1, 1000, 0);
- UploadTimer = SetTimer(1, 1000, 0);
-
- // Resize the window so all the controls adjust properly
- GetParentFrame()->GetClientRect(&rect);
- OnSize(SIZE_RESTORED, rect.right - 4, rect.bottom - 4);
-
- // restore file list
- m_ReadSavedTransfers();
-
- }
-
- void CViewTransfer::OnSize(UINT nType, int cx, int cy)
- {
- if(m_lstDownloads.m_hWnd != NULL)
- {
- RECT rectWnd,
- rectDownloads,
- rectUploads,
- rectStcDown,
- rectStcUp,
- rectBtnPause,
- rectBtnCancelUp,
- rectBtnCancelDown;
-
- GetWindowRect(&rectWnd);
- m_lstDownloads.GetWindowRect(&rectDownloads);
- m_lstUploads.GetWindowRect(&rectUploads);
- m_stcDownloads.GetWindowRect(&rectStcDown);
- m_stcUploads.GetWindowRect(&rectStcUp);
- m_btnPause.GetWindowRect(&rectBtnPause);
- m_CancelUp.GetWindowRect(&rectBtnCancelUp);
- m_CancelDown.GetWindowRect(&rectBtnCancelDown);
-
- int top_lstDownloads = rectDownloads.top - rectWnd.top - 2;
- int left_lstDownloads = rectDownloads.left - rectWnd.left - 2;
- // int right_lstDownloads = rectDownloads.right - rectDownloads.left;
- // int bottom_lstDownloads = rectDownloads.bottom - rectDownloads.top;
-
- // int top_lstUploads = rectUploads.top - rectWnd.top - 2;
- int left_lstUploads = rectUploads.left - rectWnd.left - 2;
- // int right_lstUploads = rectUploads.right - rectUploads.left;
- // int bottom_lstUploads = rectUploads.bottom - rectUploads.top;
-
- // int top_stcDown = rectStcDown.top - rectWnd.top - 2;
- // int left_stcDown = rectStcDown.left - rectWnd.left - 2;
- // int right_stcDown = rectStcDown.right - rectStcDown.left;
- int bottom_stcDown = rectStcDown.bottom - rectStcDown.top;
-
- // int top_stcUp = rectStcUp.top - rectWnd.top - 2;
- int left_stcUp = rectStcUp.left - rectWnd.left - 2;
- int right_stcUp = rectStcUp.right - rectStcUp.left;
- int bottom_stcUp = rectStcUp.bottom - rectStcUp.top;
-
- // int top_btnPause = rectBtnPause.top - rectWnd.top - 2;
- int left_btnPause = rectBtnPause.left - rectWnd.left - 2;
- int right_btnPause = rectBtnPause.right - rectBtnPause.left;
- int bottom_btnPause = rectBtnPause.bottom - rectBtnPause.top;
-
- // int top_btnCancelUp = rectBtnCancelUp.top - rectWnd.top - 2;
- int left_btnCancelUp = rectBtnCancelUp.left - rectWnd.left - 2;
- int right_btnCancelUp = rectBtnCancelUp.right - rectBtnCancelUp.left;
- int bottom_btnCancelUp = rectBtnCancelUp.bottom - rectBtnCancelUp.top;
-
- // int top_btnCancelDown = rectBtnCancelDown.top - rectWnd.top - 2;
- int left_btnCancelDown = rectBtnCancelDown.left - rectWnd.left - 2;
- int right_btnCancelDown = rectBtnCancelDown.right - rectBtnCancelDown.left;
- int bottom_btnCancelDown = rectBtnCancelDown.bottom - rectBtnCancelDown.top;
-
- m_lstDownloads.MoveWindow(left_lstDownloads, top_lstDownloads, cx - 17, cy / 2 - bottom_stcDown - bottom_btnCancelDown - 25);
- m_CancelDown.MoveWindow (left_btnCancelDown, cy / 2 - 7 - bottom_btnCancelDown, right_btnCancelDown, bottom_btnCancelDown);
- m_btnPause.MoveWindow (left_btnPause, cy / 2 - 7 - bottom_btnPause, right_btnPause, bottom_btnPause);
-
- m_stcUploads.MoveWindow(left_stcUp, cy / 2 + 10, right_stcUp, bottom_stcUp);
- m_lstUploads.MoveWindow(left_lstUploads, cy / 2 + bottom_stcUp + 10, cx - 17, cy / 2 - bottom_stcUp - bottom_btnCancelUp - 25);
- m_CancelUp.MoveWindow (left_btnCancelUp, cy - bottom_btnCancelUp - 8, right_btnCancelUp, bottom_btnCancelUp);
-
- // Resize columns
- int offSet;
-
- if(m_lstDownloads.GetScrollLimit(SB_VERT))
- offSet = ::GetSystemMetrics(SM_CXVSCROLL) + 3;
- else
- offSet = 4;
-
- CRect rect;
- m_lstDownloads.GetWindowRect(&rect);
-
- m_lstDownloads.SetColumnWidth(0, (rect.Width() - offSet) * 2/6);
- m_lstDownloads.SetColumnWidth(1, (rect.Width() - offSet) * 1/6);
- m_lstDownloads.SetColumnWidth(2, (rect.Width() - offSet) * 1/6);
- m_lstDownloads.SetColumnWidth(3, (rect.Width() - offSet) * 1/6);
- m_lstDownloads.SetColumnWidth(4, (rect.Width() - offSet) * 1/6);
-
-
- if(m_lstUploads.GetScrollLimit(SB_VERT))
- offSet = ::GetSystemMetrics(SM_CXVSCROLL) + 3;
- else
- offSet = 4;
-
- m_lstUploads.GetWindowRect(&rect);
-
- m_lstUploads.SetColumnWidth(0, (rect.Width() - offSet) * 2/6);
- m_lstUploads.SetColumnWidth(1, (rect.Width() - offSet) * 1/6);
- m_lstUploads.SetColumnWidth(2, (rect.Width() - offSet) * 1/6);
- m_lstUploads.SetColumnWidth(3, (rect.Width() - offSet) * 1/6);
- m_lstUploads.SetColumnWidth(4, (rect.Width() - offSet) * 1/6);
- }
-
- CFormView::OnSize(nType, cx, cy);
-
- }
-
-
- void CViewTransfer::OnTimer(UINT nIDEvent)
- {
- int decimal, sign;
-
- if(nIDEvent == DownloadTimer)
- {
- QueryItem lstItem;
-
- // Turn queued downloads into active downloads, if there's room available
- int ActiveDownloads = 0;
-
- for(int i = 0; i < m_lstDownloads.GetItemCount(); i++)
- if("Downloading" == m_lstDownloads.GetItemText(i, m_lstDownloads.GetColumnNumber("Status")) ||
- "Remotely queued" == m_lstDownloads.GetItemText(i, m_lstDownloads.GetColumnNumber("Status")) ||
- -1 != m_lstDownloads.GetItemText(i, m_lstDownloads.GetColumnNumber("Status")).Find("Connecting"))
- ActiveDownloads++;
-
- i = 0;
- while(i < m_lstDownloads.GetItemCount() && (ActiveDownloads < Doc->m_MaxDownloads || Doc->m_MaxDownloads == 0))
- {
- if(m_lstDownloads.GetItemText(i, m_lstDownloads.GetColumnNumber("Status") ) == "Queued")
- {
- m_lstDownloads.SetItemText(i, m_lstDownloads.GetColumnNumber("Status"), "Connecting");
-
- GetQueryItem(i, 'D')->Connect( IPtoStr( GetQueryItem(i, 'D')->FileInfo.Host), GetQueryItem(i, 'D')->FileInfo.Port);
- GetQueryItem(i, 'D')->Status = "Connecting";
-
- m_bItemsChanged = true;
-
- ActiveDownloads++;
- }
-
- i++;
- }
-
- // Update completed statuses
- for(int row = 0; row < m_lstDownloads.GetItemCount(); row++)
- {
- CGnuTransfer *Item = GetQueryItem(row, 'D');
-
- if(!Item)
- {
- RemoveRow(row, 'D');
- return;
- }
-
- // Update Status
- m_lstDownloads.SetItemText(row, m_lstDownloads.GetColumnNumber("Status"), Item->Status);
-
- if("Downloading" == Item->Status )
- {
- float NewRate = ( (float)Item->BytesCompleted - (float)Item->OldBytesCompleted ) / (float)1024;
- CString Rate = _fcvt( (NewRate + Item->OldRate) / (float) 2 , 2, &decimal, &sign );
- Rate.Insert(decimal, ".");
- m_lstDownloads.SetItemText(row, m_lstDownloads.GetColumnNumber("Rate"), Rate + " KB/s");
-
- Item->OldBytesCompleted = Item->BytesCompleted;
- Item->OldRate = NewRate;
-
- UpdateRate = 0;
-
-
- // Update the percentage
- CString Percentage;
- Percentage = _fcvt((float)Item->BytesCompleted / (float)Item->FileSize * (float)100, 0, &decimal, &sign );
-
- if(Percentage == "")
- Percentage = "0";
-
- Percentage += "% )";
-
- m_lstDownloads.SetItemText(row, m_lstDownloads.GetColumnNumber("Completed"), CommaIze( DWrdtoStr(Item->BytesCompleted)) + " ( " + Percentage);
-
- }
- else if("Completed" == m_lstDownloads.GetItemText(row, m_lstDownloads.GetColumnNumber("Status")) )
- {
- m_lstDownloads.SetItemText(row, m_lstDownloads.GetColumnNumber("Completed"), "");
- m_lstDownloads.SetItemText(row, m_lstDownloads.GetColumnNumber("Rate"), "");
-
- if(Doc->m_AutoClearDL)
- RemoveRow(row, 'D');
-
- m_bItemsChanged = true;
- }
-
- // Time out timed out items.
- /*
- *** THIS ERRORS OUT ON COMPLETION OF A PUSHED DOWNLOAD, NO IDEA WHY
- if( Item->GetSecondsSinceLastContact() > Doc->m_TimeoutDownload )
- {
- GetQueryItem(row, 'D')->Status = "No response (paused)";
- m_bItemsChanged = true;
- GetQueryItem(row, 'D')->Pause();
- }
- */
- else if(Item->Status.Find("Connecting") != -1)
- {
- CString MaxDots;
- for(int i = 0; i < Doc->m_TimeoutDownload / 5; i++)
- MaxDots += ".";
-
- if(Item->Status.Find(MaxDots) != -1)
- {
- Doc->GnuComm->NewPushRequest( Item->FileInfo );
- // RemoveRow(row, 'D');
- GetQueryItem(row, 'D')->Status = "Trying push";
- }
-
- if(FiveSecs >= 5)
- {
- Item->Status += '.';
-
- FiveSecs = 0;
- }
- else
- FiveSecs++;
-
- m_lstDownloads.SetItemText(row, m_lstDownloads.GetColumnNumber("Rate"), "");
- }
- else
- {
- if(Item->FileSize == Item->BytesCompleted)
- Item->Status = "Completed";
-
- m_lstDownloads.SetItemText(row, m_lstDownloads.GetColumnNumber("Rate"), "");
- }
- }
-
- if(m_bItemsChanged)
- {
- // update saved file of statuses
- m_SaveAllTransfers();
-
- m_bItemsChanged = false;
- }
-
- // update the button status for when text changes.
- m_UpdateDownloadButtons();
-
- }
- if(nIDEvent == UploadTimer)
- {
- Doc->ActiveUploads = 0;
-
- for(int i = 0; i < m_lstUploads.GetItemCount(); i++)
- if("Uploading" == m_lstUploads.GetItemText(i, m_lstUploads.GetColumnNumber("Status")))
- Doc->ActiveUploads++;
-
- for(int row = 0; row < m_lstUploads.GetItemCount(); row++)
- {
- CGnuTransfer *Item = GetQueryItem(row, 'U');
-
- if(!Item)
- {
- RemoveRow(row, 'U');
- return;
- }
-
- if("Uploading" == m_lstUploads.GetItemText(row, m_lstUploads.GetColumnNumber("Status")) )
- {
- // If there's a bandwidth limitation set, allocate some
- if(Doc->m_LimitUp)
- Item->AllocBw = Doc->m_LimitUp * 1024 / Doc->ActiveUploads;
- else
- Item->AllocBw = -1;
-
- // Update rate
- float NewRate = ( (float)Item->BytesCompleted - (float)Item->OldBytesCompleted ) / (float)1024;
- CString Rate = _fcvt( (NewRate + Item->OldRate) / (float) 2 , 2, &decimal, &sign );
- Rate.Insert(decimal, ".");
- m_lstUploads.SetItemText(row, m_lstUploads.GetColumnNumber("Rate"), Rate + " KB/s");
-
- Item->OldBytesCompleted = Item->BytesCompleted;
- Item->OldRate = NewRate;
-
- // Update percentage
- CString Percentage;
- Percentage = _fcvt((float)Item->BytesCompleted / (float)Item->FileSize * (float)100, 0, &decimal, &sign );
-
- if(Percentage == "")
- Percentage = "0";
-
- Percentage += "% )";
-
- m_lstUploads.SetItemText(row, m_lstUploads.GetColumnNumber("Completed"), CommaIze( DWrdtoStr(Item->BytesCompleted)) + " ( " + Percentage);
- }
- else if("Completed" == m_lstUploads.GetItemText(row, m_lstUploads.GetColumnNumber("Status")) )
- {
- m_lstUploads.SetItemText(row, m_lstUploads.GetColumnNumber("Completed"), "");
- m_lstUploads.SetItemText(row, m_lstUploads.GetColumnNumber("Rate"), "");
-
- if(Doc->m_AutoClearUL)
- RemoveRow(row, 'U');
- }
- else
- m_lstUploads.SetItemText(row, m_lstUploads.GetColumnNumber("Rate"), "");
-
- // Update Status
- m_lstUploads.SetItemText(row, m_lstUploads.GetColumnNumber("Status"), Item->Status);
- }
- }
-
- CFormView::OnTimer(nIDEvent);
- }
-
- void CViewTransfer::NewDownload(QueryItem Item, SOCKET sock)
- {
- m_bItemsChanged = true;
-
- Item.Handle = m_lstDownloads.GetItemCount();
- Item.TransferType = 'D';
-
- if(!Item.Status.GetLength()) // check to see if they may be passed status
- Item.Status = "Queued";
-
- // Setup new download with unique file name
- if(Item.LocalFileName.IsEmpty())
- {
- CFileFind finder;
- CString increment_insert;
- int increment = 1;
- int period_index = Item.FileName.ReverseFind(_T('.'));
- Item.LocalFileName = Item.FileName;
- // check to see if it exists already.
- while(finder.FindFile(((CGnucleusDoc *)GetDocument())->m_DownloadDir + "\\" + Item.LocalFileName))
- {
- increment_insert.Format("[%u]", increment++);
- // rename
- Item.LocalFileName = Item.FileName;
-
- if(period_index == -1) // add to end if there is no period, thus no extension.
- Item.LocalFileName += increment_insert;
- else
- Item.LocalFileName.Insert( period_index, increment_insert );
- }
- }
-
- Doc->GnuComm->AddTransfer(Item, sock);
-
- m_lstDownloads.InsertItem(Item.Handle, "");
- m_lstDownloads.SetItemText(Item.Handle, m_lstDownloads.GetColumnNumber( "File"), Item.FileName);
- m_lstDownloads.SetItemText(Item.Handle, m_lstDownloads.GetColumnNumber( "Bytes"), CommaIze(DWrdtoStr(Item.Size)));
- m_lstDownloads.SetItemText(Item.Handle, m_lstDownloads.GetColumnNumber( "Status"), Item.Status);
-
- int index = GetIconIndexFromName(Item.FileName);
- if(index != -1)
- {
- m_lstDownloads.SetItem(Item.Handle, 0, LVIF_IMAGE, NULL, index, m_lstDownloads.GetColumnNumber("File" ) , 0, NULL);
- }
- }
-
- extern std::map <GUID, QueryItem, CompareGuids> g_pushList;
-
- void CViewTransfer::NewPushDownload(std::string& pushString, SOCKET sock)
- {
- if (pushString.size() > MAX_PATH)
- {
- // Hostile or buggy client, disconnect
- CAsyncSocket tempSock;
-
- tempSock.Attach (sock);
-
- tempSock.Close ();
-
- return;
- }
-
- DWORD ref = 0;
- TCHAR guid[40];
- TCHAR fileName[MAX_PATH];
- guid[0] = fileName[0] = 0;
-
- ::sscanf (pushString.c_str (), "GIV %d: %32s/%*s", &ref, guid);
-
- GUID tempGuid;
-
- // shield your eyes from this next code
- unsigned char* tempGuidPtr = (unsigned char*) &tempGuid;
- ::sscanf (guid, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
- &tempGuidPtr[0],
- &tempGuidPtr[1],
- &tempGuidPtr[2],
- &tempGuidPtr[3],
- &tempGuidPtr[4],
- &tempGuidPtr[5],
- &tempGuidPtr[6],
- &tempGuidPtr[7],
- &tempGuidPtr[8],
- &tempGuidPtr[9],
- &tempGuidPtr[10],
- &tempGuidPtr[11],
- &tempGuidPtr[12],
- &tempGuidPtr[13],
- &tempGuidPtr[14],
- &tempGuidPtr[15]);
-
- tempGuid.Data1 ^= ref; // We can't use the straight guid
- tempGuid.Data2 ^= (ref << 1); // just xor some of the values in the guid
-
- std::map <GUID, QueryItem, CompareGuids>::iterator tempIt = g_pushList.find (tempGuid);
-
- if (tempIt == g_pushList.end ())
- {
- // It appears that there are malicious hosts that send out pushes.
- // ASSERT (FALSE);
- CAsyncSocket tempSock;
-
- tempSock.Attach (sock);
-
- tempSock.Close ();
-
- return;
- }
-
- std::string::iterator it;
-
- for (it = pushString.begin (); it != pushString.end (); it++)
- {
- if (*it == '/')
- {
- it++;
- break;
- }
- }
-
- std::string temp;
-
- temp.assign (it, pushString.end ());
-
- QueryItem item = (*tempIt).second;
-
- item.FileName = temp.c_str ();
- item.Index = ref;
- item.Status = "Remotely queued";
-
- NewDownload (item, sock);
-
- g_pushList.erase (tempIt); // Remove the file from the PUSH list once the transfer begins
-
- /*
- ((CGnucleusApp *) AfxGetApp())->TransferFrame->ShowWindow(SW_SHOW);
- ((CGnucleusApp *) AfxGetApp())->TransferFrame->BringWindowToTop();
- */
- }
-
- CGnuTransfer* CViewTransfer::GetQueryItem(int row, char type)
- {
- CGnuTransfer *Item = Doc->GnuComm->GetTransfer(row, type);
-
- if(Item)
- return Item;
- else
- return NULL;
-
- return NULL;
- }
-
- void CViewTransfer::RemoveRow(int deadRow, char type)
- {
- Doc->GnuComm->RemoveTransfer(deadRow, type);
-
- if(type == 'D')
- { for(int i = deadRow + 1; i < m_lstDownloads.GetItemCount(); i++)
- {
- if(GetQueryItem(i, 'D'))
- GetQueryItem(i, 'D')->Handle--;
- }
-
- m_lstDownloads.DeleteItem(deadRow);
- }
- else
- {
- for(int i = deadRow + 1; i < m_lstUploads.GetItemCount(); i++)
- {
- if(GetQueryItem(i, 'U'))
- GetQueryItem(i, 'U')->Handle--;
- }
-
- m_lstUploads.DeleteItem(deadRow);
- }
-
-
- m_bItemsChanged = true;
- }
-
-
- void CViewTransfer::OnButtonCancelDown()
- // To have fun with multiple cancles and pauses go to the dialog view, get the properties
- // of the listbox and turn off the check on single item selection
- // but dont keep it like that until it works =)
- {
- int nItem;
- POSITION pos = m_lstDownloads.GetFirstSelectedItemPosition();
-
- while(pos != NULL)
- {
- pos = m_lstDownloads.GetFirstSelectedItemPosition(); // *** Other wise it skips selections because of deleation from front ***
- nItem = m_lstDownloads.GetNextSelectedItem(pos);
- RemoveRow(nItem, 'D');
- m_bItemsChanged = true;
- }
- }
-
- ////////////////////////////////////////////////////////////
- //! author="Nathan Brown"
- //
- //: Pauses and resumes files, depending on caption status.
- void CViewTransfer::OnButtonPause()
- {
- int nItem = -1;
- POSITION pos = m_lstDownloads.GetFirstSelectedItemPosition();
- CString str_item_text;
-
- // Same thing as above
- while(pos != NULL)
- {
- nItem = m_lstDownloads.GetNextSelectedItem(pos);
- str_item_text = m_lstDownloads.GetItemText(nItem, m_lstDownloads.GetColumnNumber( "Status") );
-
- if(str_item_text.Find("Connecting") != -1 ||
- str_item_text == "Remotely queued" ||
- str_item_text == "Downloading" )
- {
- GetQueryItem(nItem, 'D')->Pause();
- }
- else
- {
- // this resumes the file, resetting the sock and re-useing the CGnuTransfer object,
- GetQueryItem(nItem, 'D')->m_hSocket = INVALID_SOCKET;
- GetQueryItem(nItem, 'D')->Create(0, SOCK_STREAM, FD_READ | FD_CONNECT | FD_CLOSE, NULL);
- GetQueryItem(nItem, 'D')->Connect( IPtoStr( GetQueryItem(nItem, 'D')->FileInfo.Host), GetQueryItem(nItem, 'D')->FileInfo.Port);
- GetQueryItem(nItem, 'D')->Status = "Connecting";
- }
- }
- }
-
-
- struct SaveItem
- {
- char FileName[256]; // path to remote file
- char LocalFileName[256]; // file name in local save path.
-
- IP Host;
- WORD Port;
- DWORD Size;
-
- DWORD Speed;
- DWORD Index;
-
- int Handle;
-
- GUID Guid;
- };
-
- ////////////////////////////////////////////////////////////
- //! author="Nathan Brown"
- //
- //: Reads saved transfers from ini incase of crash, etc.
- void CViewTransfer::m_ReadSavedTransfers(void)
- {
- if(!this)
- return;
-
- // Filter Settings
- int loop;
-
- CString str_file_name,
- str_server_name_port;
- DWORD dw_file_size = 0;
- LVFINDINFO FindInfo;
- SaveItem transfer_item;
-
- CFileFind finder;
-
- for (loop = 0; ; ++loop)
- {
- // gather items for connections
- QueryItem qi_transfer_item;
- CString temp;
- temp.Format ("File%2.2d", loop);
-
- if (GetPrivateProfileStruct ("Transfers", temp, (void *) &transfer_item, sizeof(SaveItem), ".\\Gnucleus.ini") )
- {
-
- /* // think I got it fixed, can't use this when using different local file names
- // Check to see if file is already in transfer list
- FindInfo.flags = LVFI_PARTIAL|LVFI_STRING;
- FindInfo.psz = &transfer_item.FileName[0];
-
- // some kind of weird problem lurks here, crashes dead, no explenation.
- if( m_lstDownloads.FindItem(&FindInfo) != -1 )
- continue; // file already in, may be different server, but continue
-
- // if not, add to list as queued.
- */
- qi_transfer_item.FileName = transfer_item.FileName;
-
- if(Doc->m_ResumeDL)
- qi_transfer_item.Status = "Queued";
- else
- qi_transfer_item.Status = "Restored";
-
- qi_transfer_item.Guid = transfer_item.Guid;
- qi_transfer_item.Handle = transfer_item.Handle;
- qi_transfer_item.Host = transfer_item.Host;
- qi_transfer_item.Port = transfer_item.Port;
- qi_transfer_item.Size = transfer_item.Size;
- qi_transfer_item.Speed = transfer_item.Speed;
- qi_transfer_item.IconIndex = 0;
- qi_transfer_item.Index = transfer_item.Index;
- qi_transfer_item.Reverse = 0;
- qi_transfer_item.SortBy = 0;
-
- // and last and most importantly:
- qi_transfer_item.BytesCompleted = 0;
- if(finder.FindFile(((CGnucleusDoc *)GetDocument())->m_DownloadDir + "\\" + transfer_item.LocalFileName)) // if it's there use the saved filesize
- {
- int length = 0;
- finder.FindNextFile();
- if( (length = finder.GetLength()) )
- qi_transfer_item.BytesCompleted = length;
-
- qi_transfer_item.LocalFileName = transfer_item.LocalFileName;
- }
- else
- qi_transfer_item.LocalFileName.Empty();
-
-
- NewDownload(qi_transfer_item);
- }
- else
- {
- break;
- }
- }
- }
-
- ////////////////////////////////////////////////////////////
- //! author="Nathan Brown"
- //
- //: Saves all transfers in ini file useing base64 encoding
- void CViewTransfer::m_SaveAllTransfers(void)
- {
- // Filter Settings
- int loop;
-
- CString str_file_name,
- str_server_name_port;
- CString temp_key;
- SaveItem transfer_item;
- QueryItem qi_transfer_item;
-
- // Clear out items
- for (loop = 0; true; ++loop)
- {
- temp_key.Format ("File%2.2d", loop);
-
- if (GetPrivateProfileStruct("Transfers", temp_key, (void *) &transfer_item, sizeof(SaveItem), ".\\Gnucleus.ini") > 0)
- WritePrivateProfileStruct ("Transfers", temp_key, NULL, sizeof(SaveItem), ".\\Gnucleus.ini"); // remove
- else
- break;
- }
-
- // write out current transfers
- for (loop = 0; loop < m_lstDownloads.GetItemCount(); ++loop)
- {
- temp_key.Format ("File%2.2d", loop);
-
- qi_transfer_item = GetQueryItem(loop, 'D')->FileInfo;
-
- strcpy(transfer_item.FileName, qi_transfer_item.FileName);
- strcpy(transfer_item.LocalFileName, qi_transfer_item.LocalFileName);
- transfer_item.Guid = qi_transfer_item.Guid;
- transfer_item.Handle = qi_transfer_item.Handle;
- transfer_item.Host = qi_transfer_item.Host;
- transfer_item.Port = qi_transfer_item.Port;
- transfer_item.Size = qi_transfer_item.Size;
- transfer_item.Speed = qi_transfer_item.Speed;
- transfer_item.Index = qi_transfer_item.Index;
-
- WritePrivateProfileStruct ("Transfers", temp_key, (void *)&transfer_item, sizeof(SaveItem), ".\\Gnucleus.ini");
-
- }
- }
-
- ////////////////////////////////////////////////////////////
- //! author="Nathan Brown"
- //
- //: Maintains correct cancel and resume/pause button status
- void CViewTransfer::m_UpdateDownloadButtons(void)
- {
- if(m_lstDownloads.GetSelectedCount())
- {
- int n_item;
- bool b_pause = false,
- b_activate = false;
- POSITION pos = m_lstDownloads.GetFirstSelectedItemPosition();
-
- while(pos)
- {
- n_item = m_lstDownloads.GetNextSelectedItem(pos);
-
- CString str_item_text = m_lstDownloads.GetItemText(n_item, m_lstDownloads.GetColumnNumber( "Status"));
-
- if(str_item_text.Find("Connecting") != -1 ||
- str_item_text == "Remotely queued" ||
- str_item_text == "Downloading" )
- {
- b_pause = true;
- }
-
- // need to make sure all possible strings that can resume are listed here.
- if(str_item_text == "Paused" ||
- str_item_text == "Queued" ||
- str_item_text == "Restored" ||
- str_item_text == "Connection Refused" ||
- str_item_text == "HTTP 404 Error" ||
- str_item_text == "HTTP 200 Error" ||
- str_item_text == "Remotely Canceled" ||
- str_item_text == "Trying push" ||
- str_item_text == "Bad Header")
- {
- b_activate = true;
- }
-
- // make sure we are only going one way. disable otherwise.
- if(b_activate && b_pause)
- {
- m_CancelDown.EnableWindow(TRUE); // can cancel if any selected
- m_btnPause.EnableWindow(FALSE);
- return;
-
- }
-
- }
-
- m_CancelDown.EnableWindow(TRUE);
- // well it all went well, so enable the button one way or the other
- if(b_activate || b_pause)
- {
- m_btnPause.SetWindowText(b_activate ? "Activate" : "Pause" );
- m_btnPause.EnableWindow(TRUE);
- }
- else
- {
- m_btnPause.EnableWindow(FALSE);
- }
-
- }
- else
- {
- m_CancelDown.EnableWindow(FALSE);
- m_btnPause.EnableWindow(FALSE);
- }
-
- }
-
- ////////////////////////////////////////////////////////////
- //! author="Nathan Brown"
- //
- //: Maintains correct cancel and resume/pause button status
- void CViewTransfer::OnItemchangedListDownloads(NMHDR* pNMHDR, LRESULT* pResult)
- {
- NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
- *pResult = 0;
-
- if( (pNMListView->uChanged & LVIF_STATE) == LVIF_STATE )
- {
- // Doesn't work for when the text changes, need to fix that later.
- if((pNMListView->uNewState & LVIS_SELECTED)
- | (pNMListView->uOldState & LVIS_SELECTED))
- m_UpdateDownloadButtons();
- }
- else // if what changed is not what we are interested in, don't worry about it.
- return;
- }
-
- void CViewTransfer::NewUpload(CString Header, SOCKET sock)
- {
- // If its past the max uploads drop it
- if(Doc->m_MaxUploads)
- if(Doc->m_MaxUploads <= Doc->ActiveUploads)
- return;
-
- DWORD index;
- TCHAR name[256];
- DWORD bytes = 0;
-
- ::sscanf(Header, "GET /get/%ld/%s HTTP/1.0\r\n", &index, name);
- CString FileName(Header.Mid( Header.Find(name), Header.Find(" HTTP/1.0") - Header.Find(name)));
-
- bool found = 0;
-
- if(Header.Find("bytes=") != -1)
- {
- int pos = Header.Find("bytes=") + 6;
- bytes = atol( Header.Mid(pos, Header.Find("-\r\n") - pos));
- found = 1;
- }
-
- QueryItem Item;
-
- if(found)
- Item.BytesCompleted = bytes;
- else
- Item.BytesCompleted = 0;
-
- // Find file in the list
- std::vector<SharedFile>::iterator itName;
- std::vector<DWORD>::iterator itSize;
-
- CString ShortName;
-
- DWORD loop = 0;
- for(loop = 0, itName = Doc->SharedFiles.begin(), itSize = Doc->SharedSizes.begin();
- itName != Doc->SharedFiles.end(), itSize != Doc->SharedSizes.end();
- loop++, itName++, itSize++)
- {
- if(loop == index)
- if(FileName != (*itName).FileName)
- return;
- else
- {
- ShortName = (*itName).FileName;
-
- Item.FileName = (*itName).FileDir;
- Item.Size = *itSize;
- Item.Index = loop;
- }
- }
-
- if(index > loop)
- return;
-
- // Setup structure and list
- Item.Handle = m_lstUploads.GetItemCount();
- Item.TransferType = 'U';
- Item.Status = "Connecting";
-
-
- m_lstUploads.InsertItem(Item.Handle, "" );
- m_lstUploads.SetItemText(Item.Handle, m_lstUploads.GetColumnNumber( "File"), ShortName);
- m_lstUploads.SetItemText(Item.Handle, m_lstUploads.GetColumnNumber( "Bytes"), CommaIze(DWrdtoStr(Item.Size)));
- m_lstUploads.SetItemText(Item.Handle, m_lstUploads.GetColumnNumber( "Status"), Item.Status);
-
- int icon = GetIconIndexFromName(ShortName);
- if(icon != -1)
- m_lstUploads.SetItem(Item.Handle, 0, LVIF_IMAGE, NULL, icon, m_lstUploads.GetColumnNumber( "File"), 0, NULL);
-
- // A normal upload
- if(sock)
- {
- Doc->GnuComm->AddTransfer(Item, sock);
- GetQueryItem(Item.Handle, 'U')->StartSending();
- }
- // A push upload
- else
- {
- CGnuTransfer *Push = GetQueryItem(16000, 'U');
-
- if(Push)
- {
- Push->FileInfo = Item;
- Push->Handle = Item.Handle;
- Push->FileSize = Item.Size;
-
- GetQueryItem(Item.Handle, 'U')->StartSending();
- }
- }
-
-
- }
-
- void CViewTransfer::OnButtonCancelUp()
- {
- int nItem;
- POSITION pos = m_lstUploads.GetFirstSelectedItemPosition();
-
- while(pos != NULL)
- {
- pos = m_lstUploads.GetFirstSelectedItemPosition(); // *** Other wise it skips selections because of deleation from front ***
- nItem = m_lstUploads.GetNextSelectedItem(pos);
- RemoveRow(nItem, 'U');
- }
- }
-